/*============================================================================
  File:      lrsstatreader.cpp
 
  Summary:   Implementation of LRSSTATREADER class for collecting the
			 sufficient statistics for the pair-wise linear regression model.
 
  Date:		 June 30, 2004
------------------------------------------------------------------------------
  This file is part of the Microsoft SQL Server Code Samples.
 
  Copyright (C) 2003 Microsoft Corporation.  All rights reserved.
 
This source code is intended only as a supplement to Microsoft
Development Tools and/or on-line documentation.  See these other
materials for detailed information regarding Microsoft code samples.
 
THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
============================================================================*/

#include "stdafx.h"
#include "lrsstatreader.h"
#include "DataValues.h"

HRESULT	LRSSTATREADER::Initialize(CComPtr<IDMAttributeSet>& spidmattributeset)
{
	HRESULT hr = spidmattributeset->GetAttributeCount(&_cAttribute);

	RETURN_ON_FAIL(hr);

	_cCase		= 0;

	_viAttributeInput.resize(0);
	_viAttributeOutput.resize(0);

	_ciAttributeInput	= 0;
	_ciAttributeOutput	= 0;

	for (ULONG iAttribute = 0; iAttribute < _cAttribute; iAttribute++)
	{
		DM_ATTRIBUTE_FLAGS dmattributeflags = 0;

		hr = spidmattributeset->GetAttributeFlags(iAttribute, &dmattributeflags);

		RETURN_ON_FAIL(hr);

		if (dmattributeflags & DMAF_INPUT)
		{
			_viAttributeInput.push_back(iAttribute);
			_ciAttributeInput++;
		}

		if (dmattributeflags & DMAF_OUTPUT)
		{
			_viAttributeOutput.push_back(iAttribute);
			_ciAttributeOutput++;
		}
	}
	
	// Initialize all counts to 0

	_vvdblSumProducts.resize(_ciAttributeOutput);

	for (ULONG iiAttributeOutput = 0; iiAttributeOutput < _ciAttributeOutput; iiAttributeOutput++)
	{
		_vvdblSumProducts[iiAttributeOutput].resize(_ciAttributeInput, 0.0);
	}

	_vdblSum.resize(_cAttribute, 0.0);
	_vdblSumSquares.resize(_cAttribute, 0.0);

	_vdblMin.resize(_cAttribute, 0.0);
	_vdblMax.resize(_cAttribute, 0.0);

	return S_OK;
}


HRESULT LRSSTATREADER::ProcessCaseDense(ULONG ulID, VDBL& vdblValue)
{
	// Update counts according to the case:

	// First update the matrix of products, indexed by the index of the attribute
	// number.

	for (UINT iiAttributeOut = 0; iiAttributeOut < _ciAttributeOutput; iiAttributeOut++)
	{
		ULONG	iAttributeOutput	= _viAttributeOutput[iiAttributeOut];
		DBL		dblValueOut			= vdblValue[iAttributeOutput];

		if (dblValueOut == dblMissing)
		{
			// We don't handle missing values

			return E_FAIL;
		}

		for (UINT iiAttributeIn = 0; iiAttributeIn < _ciAttributeInput; iiAttributeIn++)
		{
			ULONG	iAttributeInput	= _viAttributeInput[iiAttributeIn];
			DBL		dblValueIn		= vdblValue[iAttributeInput];

			DBL dblProd = dblValueOut * dblValueIn;

			_vvdblSumProducts[iiAttributeOut][iiAttributeIn] += dblProd;
		}
	}

	// Now update sums and sum-of-squares, indexed by the attribute number

	for (UINT iAttribute = 0; iAttribute < _cAttribute; iAttribute++)
	{
		DBL	dblValue = vdblValue[iAttribute];

		_vdblSum[iAttribute]		+= dblValue;
		_vdblSumSquares[iAttribute]	+= dblValue * dblValue;
	}

	// Finally, update the min and max values, indexed by attribute number

	if (_cCase == 0)
	{
		for (UINT iAttribute = 0; iAttribute < _cAttribute; iAttribute++)
		{
			_vdblMin[iAttribute] = vdblValue[iAttribute];
			_vdblMax[iAttribute] = vdblValue[iAttribute];
		}
	}
	else
	{
		for (UINT iAttribute = 0; iAttribute < _cAttribute; iAttribute++)
		{
			if (_vdblMin[iAttribute] > vdblValue[iAttribute])
			{
				_vdblMin[iAttribute] = vdblValue[iAttribute];
			}

			if (_vdblMax[iAttribute] < vdblValue[iAttribute])
			{
				_vdblMax[iAttribute] = vdblValue[iAttribute];
			}
		}
	}

	_cCase++;

	return S_OK;
}
				  
